package com.hyts.jgit.handler;

import com.hyts.jgit.base.model.ResultModel;
import com.hyts.jgit.base.spi.LocalBaseSpi;
import com.hyts.jgit.bean.LocalOperateModel;
import com.hyts.jgit.config.GitParamConfiguration;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.CreateBranchCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.revwalk.RevCommit;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * project-name:coffice-toolbox
 * package-name:com.hyts.gitclient.handler
 * author:Libo/Alex
 * create-date:2019-06-14 23:29
 * copyright:libo-hyts-github
 * email:libo2dev@aliyun.com
 * description:此类主要用于: local本地基础操作
 */
@Builder
@Slf4j
public class LocalBaseHandler implements LocalBaseSpi<LocalOperateModel, ResultModel<Object>> {

    /**
     * checkout服务
     * @param param
     * @return
     */
    @Override
    public ResultModel<Object> checkout(LocalOperateModel param) {
        File file = validateGitDir(param.getLocalRepositoryPath());
        try {
            if(!file.exists()){
               throw new FileNotFoundException("Git服务目录文件不存在!");
            }
            Git.open(file).checkout().setName(param.getLocalBranchName()).
                    setForced(param.isForce()).setAllPaths(true).setCreateBranch(param.isCreate()).
                    setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.SET_UPSTREAM).
                    call();
        } catch (IOException | GitAPIException e) {
            return ResultModel.failure("切换分支失败！");
        }
        return ResultModel.success("切换分支成功!");
    }

    /**
     * 查询信息状态
     * @param param
     * @return
     */
    @Override
    public ResultModel<Object> lookStatus(LocalOperateModel param) {
        File file = validateGitDir(param.getLocalRepositoryPath());
        try {
            if(!file.exists()){
                throw new FileNotFoundException("Git服务目录文件不存在!");
            }
            Status status = Git.open(file).status().call();
            return ResultModel.success("成功切换分支").setData(status);
        } catch (IOException | GitAPIException e) {
            return ResultModel.failure("切换分支失败！");
        }
    }

    /**
     * 查询log日志
     * @param param
     * @return
     */
    @Override
    public ResultModel<Object> lookLog(LocalOperateModel param) {
        File file = validateGitDir(param.getLocalRepositoryPath());
        try {
            if(!file.exists()){
                throw new FileNotFoundException("Git服务目录文件不存在!");
            }
            Iterable<RevCommit> revCommits = Git.open(file).log().addPath(param.getLocalRepositoryPath()).call();
            return ResultModel.success("成功切换分支").setData(revCommits);
        } catch (IOException | GitAPIException e) {
            return ResultModel.failure("切换分支失败！");
        }
    }


    private static File validateGitDir(String path){
        if(!path.endsWith(File.separator)){
            path+=File.separator;
        }
        File file = new File(path+ GitParamConfiguration.DEFAULT_GIT_REPOSITORY_PATH);
        return file;
    }

    /**
     * 初始化操作服务
     * @param param
     * @return
     */
    @Override
    public ResultModel<Object> init(LocalOperateModel param) {
        //path路径操作服务
        Path path = Paths.get(param.getLocalRepositoryPath());
        //判断文件是否存在
        try {
            boolean result = Files.deleteIfExists(path);
            if(result)
                log.error("删除文件失败！");
            Git.open(Files.createDirectory(Paths.get(param.getLocalRepositoryPath(),
                    GitParamConfiguration.DEFAULT_GIT_REPOSITORY_PATH)).toFile()).init().call();
            return ResultModel.success("初始化git文件系统失败!");
        } catch (IOException | GitAPIException e) {
            log.error("删除文件失败！",e);
            return ResultModel.failure("初始化git文件系统失败!");
        }
    }


    @Override
    public ResultModel<Object> add(LocalOperateModel param) {
        File file = validateGitDir(param.getLocalRepositoryPath());
        try {
            if(!file.exists()){
                throw new FileNotFoundException("Git服务目录文件不存在!");
            }
            Git.open(file).add().addFilepattern(param.getFilePattern())/*.setUpdate(true)*/.call();
            return ResultModel.success("成功添加文件到索引中");
        } catch (IOException | GitAPIException e) {
            return ResultModel.failure("失败添加文件到索引中！");
        }
    }

    @Override
    public ResultModel<Object> revert(LocalOperateModel param) {
        return null;
    }


    @Override
    public ResultModel<Object> commit(LocalOperateModel param) {
        File file = validateGitDir(param.getLocalRepositoryPath());
        try {
            if(!file.exists()){
                throw new FileNotFoundException("Git服务目录文件不存在!");
            }
            Git.open(file).commit().setAll(true).setAuthor(param.getAuthModel().getUserName(),
                    param.getAuthModel().getPassword()).setCommitter(param.getAuthModel().getUserName(),
                    param.getAuthModel().getPassword()).setMessage(param.getMessage()).call();
            return ResultModel.success("成功提交索引分支");
        } catch (IOException | GitAPIException e) {
            return ResultModel.failure("提交文件索引失败！");
        }
    }


}
